home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / tools / sharp / xc2103.lzh / ASK30 / KANJISEL.C < prev    next >
C/C++ Source or Header  |  1993-09-15  |  7KB  |  363 lines

  1. /*
  2. **    部首名検索 for ASK3
  3. **    Copyright (C) 1992  ACCESS CO.,LTD.
  4. */
  5. #include "aci.h"
  6. #include "askkey.h"
  7. typedef unsigned char    u_char;
  8.  
  9. short    acc_main();
  10. u_char    cbuf[80];
  11. MEAN    kbuf[81];
  12. MEAN    mbuf[9];
  13. ACC_DEF    acc = {
  14.     KS_EDIT0|KS_EDITING,
  15.     CTRL_ON|NOT_ASCII|CODE_IN,
  16.     acc_main,
  17.     {
  18.         cbuf,    kbuf,    mbuf
  19.     }
  20. };
  21.  
  22. #define    BUFSIZE    1024
  23. static u_char    line[BUFSIZE];    /* 読み込みバッファ */
  24. static u_char    *linep;        /* 文字へのポインタ*/
  25. static u_char    dicname[64];    /* 辞書ファイル */
  26. static int    fd;
  27.  
  28. short    acc_main(code)
  29. BIT16    code;
  30. {
  31.     BIT16    nc, mask_key();
  32.     u_char    *strcpy();
  33.     void    next_moji(), next_bushu(), next_kakusu(), enter();
  34.     static u_char    askinput[80];    /* 仮入力文字列 */
  35.     static int    first = 1;
  36.     static int    second = 0;
  37.     static int    urgent = 0;
  38.  
  39.     /* CACI_URGENT はメッセージを表示するために    */
  40.     /* 一瞬ASKに処理を戻すために使っている    */
  41.     if (first) {
  42.         first = 0;
  43.         second = 1;
  44.         strcpy(askinput, cbuf);
  45.         sstrtom("部首検索", mbuf, 0);
  46.         sstrtom("辞書オープン中です...", kbuf, 0);
  47.         return(DF_MWINSTR|DF_KWINSTR|CACI_URGENT);
  48.     } else if (second) {
  49.         second = 0;
  50.         if (init(dicname, askinput) < 0) {
  51.             urgent = 1;
  52.             xclose(fd);
  53.             sstrtom("部首検索辞書が不正です", kbuf, 0);
  54.             return(DF_KWINSTR|CACI_URGENT);
  55.         }
  56.         return(DF_KWINSTR|CACI_NORMAL);
  57.     } else if (urgent) {
  58.         for (urgent = 10000; urgent > 0; urgent--) {
  59.             first = 200 * 30.0 / 12.0;
  60.         }
  61.         urgent = 0;
  62.         first = 1;
  63.         xclose(fd);
  64.         return(CACI_END);
  65.     }
  66.     nc = mask_key(code);
  67.     switch(nc) {
  68.       case NOT_ASCII|LEFT_KEY:
  69.           next_moji(-1);
  70.         break;
  71.       case NOT_ASCII|RIGHT_KEY:
  72.           next_moji(1);
  73.         break;
  74.       case NOT_ASCII|UP_KEY:
  75.           next_bushu(-1);
  76.         break;
  77.       case NOT_ASCII|DOWN_KEY:
  78.           next_bushu(1);
  79.         break;
  80.       case CTRL_ON|NOT_ASCII|UP_KEY:
  81.           next_kakusu(-1);
  82.         break;
  83.       case CTRL_ON|NOT_ASCII|DOWN_KEY:
  84.           next_kakusu(1);
  85.         break;
  86.       case '\r':
  87.           enter();
  88.           return(DF_OUTSTR|CACI_SUSPEND);
  89.       case CTRL_ON|NOT_ASCII|CODE_IN:
  90.       case CTRL_ON|NOT_ASCII|CODE_OUT:
  91.       case '\033':
  92.         first = 1;
  93.         xclose(fd);
  94.         return(CACI_END);
  95.       case CTRL_ON|NOT_ASCII|XF1_KEY:
  96.         first = 1;
  97.         xclose(fd);
  98.         return(KEY_AGAIN|CACI_END);
  99.       default:
  100.         break;
  101.     }
  102.     return(DF_KWINSTR|CACI_NORMAL);
  103. }
  104.  
  105. static BIT16    mask_key(code)
  106. BIT16    code;
  107. {
  108.     code &= (0xff|CTRL_ON|SHIFT_ON|NOT_ASCII);
  109.     if (!(code & NOT_ASCII))
  110.         code &= ~CTRL_ON;
  111.     return(code);
  112. }
  113.  
  114. #define    TBLSIZE    256        /* 辞書のインデックス */
  115. static struct {
  116.     short    kakusu;        /* 画数 */
  117.     u_char    bushuname[32];    /* 部首名 */
  118.     long    offset;        /* オフセット */
  119. } block[TBLSIZE];
  120. static int    cur_block;    /* 現在の表示ブロック */
  121. static int    cur_moji;    /* 選択されている文字 */
  122. static int    totalblocks;    /* 総ブロック数 */
  123.  
  124. static int    init(fname, askinput)
  125. u_char    *fname, *askinput;
  126. {
  127.     int    i, j;
  128.     u_char    *p, *ltos();
  129.     long    lastoffset = 0;
  130.  
  131.     cur_block = cur_moji = totalblocks = -1;
  132.     if ((fd = xopen(fname, 0x0000)) < 0)
  133.         return(fd = -1);
  134.  
  135.     /* 辞書をスキャンしてオンメモリでインデックスを作る。    */
  136.     /* 辞書は1行1レコードで、                */
  137.     /*     画数,部首名,漢字並び                */
  138.     /* を1レコードとする。漢字は必ず2バイト文字。        */
  139.     for (i = 0; getline(fd, line, BUFSIZE) > 0 && i < TBLSIZE; i++) {
  140.         block[i].offset = lastoffset;
  141.         lastoffset = xseek(fd, 0, 1);
  142.         block[i].kakusu = 0;
  143.         for (p = line; *p != ','; p++) {
  144.             if (*p >= '0' && *p <= '9') {
  145.                 block[i].kakusu *= 10;
  146.                 block[i].kakusu += (*p - '0');
  147.             } else {
  148.                 return(-1);
  149.             }
  150.         }
  151.         if ((i > 0) && (block[i-1].kakusu > block[i].kakusu)) {
  152.             return(-1);    /* 画数が昇順になっていない */
  153.         }
  154.         for (j = 0, ++p; *p != ','; p += 2) {
  155.             if (*p == (u_char)0) {
  156.                 return(-1);
  157.             } else {
  158.                 block[i].bushuname[j++] = *p;
  159.                 block[i].bushuname[j++] = *(p+1);
  160.             }
  161.         }
  162.         block[i].bushuname[j] = (u_char)0;
  163.     }
  164.     if ((totalblocks = i) == 0) {
  165.         return(-1);
  166.     }
  167.  
  168.     if (*askinput != (u_char)0) {
  169.         for (i = 0; i < totalblocks; i++) {
  170.             if (strcmp(block[i].bushuname, askinput) == 0) {
  171.                 cur_block = i - 1;
  172.                 break;
  173.             }
  174.         }
  175.     }
  176.     next_bushu(1);
  177.     return(0);
  178. }
  179.  
  180. /* 表示関係。64文字モードには未対応 */
  181. #define    KWINLEN    80        /* 候補ウィンドウの長さ */
  182. #define    NKOUHO    16        /* 1行の最大文字数 */
  183.  
  184. static void    next_moji(sign)
  185. int    sign;
  186. {
  187.     u_char    *p, *makedisp();
  188.  
  189.     if (sign < 0) {                /* 前の文字 */
  190.         if (cur_moji > 0)
  191.             --cur_moji;
  192.         else
  193.             return;
  194.     } else {                /* 次の文字 */
  195.         if (*(linep + cur_moji * 2 + 2) != (u_char)0)
  196.             ++cur_moji;
  197.         else
  198.             return;
  199.     }
  200.     p = makedisp(linep + (cur_moji / NKOUHO) * NKOUHO * 2,
  201.         block[cur_block].bushuname);
  202.     sstrtom(p, kbuf, 0);
  203.     chgkind(&kbuf[(cur_moji % NKOUHO * 4) + 2], 2, 1);
  204. }
  205.  
  206. static void    next_bushu(sign)
  207. int    sign;
  208. {
  209.     u_char    *p, *makedisp();
  210.  
  211.     if (sign < 0) {                /* 前の部首 */
  212.         if (cur_block > 0)
  213.             --cur_block;
  214.         else
  215.             return;
  216.     } else {                /* 次の部首 */
  217.         if (cur_block < totalblocks-1)
  218.             ++cur_block;
  219.         else
  220.             return;
  221.     }
  222.     if (xseek(fd, block[cur_block].offset, 0) < 0)
  223.         return;
  224.     if (getline(fd, line, BUFSIZE) <= 0)
  225.         return;
  226.     linep = line;
  227.     while (*linep++ != ',') ;
  228.     while (*linep != ',') linep += 2;
  229.     p = makedisp(++linep, block[cur_block].bushuname);
  230.     sstrtom(p, kbuf, 0);
  231.     chgkind(&kbuf[2], 2, 1);
  232.     cur_moji = 0;
  233. }
  234.  
  235. static void    next_kakusu(sign)
  236. int    sign;
  237. {
  238.     int    i;
  239.  
  240.     if (sign < 0) {                /* ひとつ少ない画数 */
  241.         for (i = cur_block - 1; i >= 0; i--) {
  242.             if (block[i].kakusu < block[cur_block].kakusu)
  243.                 break;
  244.         }
  245.     } else {                /* ひとつ多い画数 */
  246.         for (i = cur_block + 1; i < totalblocks; i++) {
  247.             if (block[i].kakusu > block[cur_block].kakusu)
  248.                 break;
  249.         }
  250.     }
  251.     if (i >= 0 && i < totalblocks) {
  252.         cur_block = i - 1;
  253.         next_bushu(1);
  254.     }
  255. }
  256.  
  257. static void    enter()
  258. {
  259.     cbuf[0] = *(linep + cur_moji * 2);
  260.     cbuf[1] = *(linep + cur_moji * 2 + 1);
  261.     cbuf[2] = (u_char)0;
  262. }
  263.  
  264. static u_char    *makedisp(kanji_str, bushuname)
  265. u_char    *kanji_str, *bushuname;
  266. {
  267.     static u_char    disp_line[100];
  268.     int    i, sp;
  269.     u_char    *p = disp_line;
  270.  
  271.     for (i = 0; i < NKOUHO; i++, p += 4) {
  272.         if (*kanji_str == (u_char)0) {
  273.             break;
  274.         } else {
  275.             *p = *(p + 1) = ' ';
  276.             *(p + 2) = *kanji_str++;
  277.             *(p + 3) = *kanji_str++;
  278.         }
  279.     }
  280.     *p = (u_char)0;
  281.     i = strlen(disp_line) + strlen(bushuname);
  282.     sp = (i + 2 <= KWINLEN) ? (KWINLEN - i) : 2;
  283.     while (sp--)
  284.         *p++ = ' ';
  285.     strcpy(p, bushuname);
  286.     *(disp_line + KWINLEN) = (u_char)0;
  287.     return(disp_line);
  288. }
  289.  
  290. static int    getline(fd, buf, bufsize)
  291. int    fd;
  292. char    *buf;
  293. int    bufsize;
  294. {
  295.     u_char    inbuf[2+255+1];
  296.     int    total, len, i;
  297.  
  298.     total = 0;
  299.     inbuf[0] = 255;
  300.     while ((len = fgets(fd, inbuf)) > 0) {
  301.         for (i = 2; i < len + 2; i++) {
  302.             if (inbuf[i] == 0x1a) {
  303.                 inbuf[i] = '\0';
  304.                 len = i - 2;
  305.                 break;
  306.             }
  307.         }
  308.         if ((total + len) >= bufsize) {
  309.             return(0);
  310.         }
  311.         strcpy(&buf[total], &inbuf[2]);
  312.         total += len;
  313.         if (len < 255) {
  314.             return(total);
  315.         }
  316.     }
  317.     return(0);                /* EOF */
  318. }
  319.  
  320. static u_char *strcpy(s1, s2)
  321. u_char    *s1, *s2;
  322. {
  323.     u_char    *ret = s1;
  324.  
  325.     while (*s1++ = *s2++)
  326.         ;
  327.     return(ret);
  328. }
  329.  
  330. static int strlen(s)
  331. u_char    *s;
  332. {
  333.     u_char    *p = s;
  334.  
  335.     while (*s)
  336.         s++;
  337.     return(s - p);
  338. }
  339.  
  340. static int strcmp(s1, s2)
  341. u_char    *s1, *s2;
  342. {
  343.     while (*s1 && *s2 && *s1 == *s2) {
  344.         s1++;
  345.         s2++;
  346.     }
  347.     return(*s1 - *s2);
  348. }
  349.  
  350. int    scanarg(arg)
  351. u_char    *arg;
  352. {
  353.     while (*arg++ != 0)
  354.         ;
  355.     if (*arg == 0)
  356.         return(1);
  357.     else if (*arg == '/' && (*(arg+1) == 'D' || *(arg+1) == 'd')) {
  358.         strcpy(dicname, arg+2);
  359.         return(0);
  360.     } else
  361.         return(1);
  362. }
  363.